// 除自身以为数组元素乘积问题 暴力解是一个平方级复杂度
// 那么更好的解我们尝试 是否可以用 nLogN 级 nLogN级可能的算法有哪些?排序?建队?搜索?for循环中二分? 似乎都帮不上忙
// 这题看到最后提示有 线性时间的实现方法 那么考虑常见的一些算法 双指针? 滑动窗口？指针对撞？前缀积 后缀积 ？二次扫描
// 显然最后发现此题 通过两次扫描 求出前缀积和后缀积的乘积即为结果
// 那么进一步压缩空间复杂度 有什么好的办法？最终想到 使用空间复用的思想 用结果数组先求前缀积 在从后变流求后缀积直接相乘得到结果
// 同时继续优化 想到如果使用两个辅助数组本质上前后缀的求解可以并行进行 因此可以考虑以空间换时间的思想
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int length = nums.size();
        vector<int> answer(length);

        // answer[i] 表示索引 i 左侧所有元素的乘积
        // 因为索引为 '0' 的元素左侧没有元素， 所以 answer[0] = 1
        answer[0] = 1;
        for (int i = 1; i < length; i++) {
            answer[i] = nums[i - 1] * answer[i - 1];
        }

        // R 为右侧所有元素的乘积
        // 刚开始右边没有元素，所以 R = 1
        int R = 1;
        for (int i = length - 1; i >= 0; i--) {
            // 对于索引 i，左边的乘积为 answer[i]，右边的乘积为 R
            answer[i] = answer[i] * R;
            // R 需要包含右边所有的乘积，所以计算下一个结果时需要将当前值乘到 R 上
            R *= nums[i];
        }
        return answer;
    }
};